package cn.devcat.sso.service.impl;

import cn.devcat.sso.entity.DevcatRole;
import cn.devcat.sso.entity.DevcatUser;
import cn.devcat.sso.entity.FileStore;
import cn.devcat.sso.mapper.FileStoreMapper;
import cn.devcat.sso.service.IDevcatRoleService;
import cn.devcat.sso.service.IFileStoreService;
import cn.devcat.sso.util.FileUtils;
import cn.devcat.sso.util.TimeUtil;
import cn.devcat.sso.util.UserUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class FileStoreServiceImpl extends ServiceImpl<FileStoreMapper, FileStore> implements IFileStoreService {

  @Value("${devcat.save-file-path}")
  private String saveFileDir;

  @Value("${devcat.blog-image}")
  private String blogImageDir;

  @Autowired
  private UserUtil userUtil;

  @Autowired
  IDevcatRoleService roleService;

  @Override
  public String upload(MultipartFile file) {
    DevcatUser user = userUtil.getUserByRequest();
    List<DevcatRole> roleListByUserId = roleService.getRoleListByUserId(user.getId());
    long count = roleListByUserId.stream().filter(item -> "ROLE_ADMIN".equals(item.getRoleCode())).count();
    if (count == 0) {
      long size = file.getSize();
      if ((size / 1024 / 1024) > 10) {
        throw new RuntimeException("除管理员角色用户外，其余用户上传单个文件大小应小于10MB，感谢理解");
      }
    }
    String originalFilename = file.getOriginalFilename();
    String suffix = FileUtils.suffix(originalFilename);
    String saveFileName = TimeUtil.getDateTime("yyyyMMddHHmmss");
    FileUtils.mkdir(saveFileDir + "upload");
    String newFilePath = saveFileDir + "upload/" + saveFileName + suffix;
    try {
      file.transferTo(new File(newFilePath));
    } catch (IOException e) {
      throw new RuntimeException("保存文件失败");
    }
    String userId = userUtil.getUserByRequest().getId();
    FileStore fileStore = new FileStore();
    fileStore.setUploadTime(LocalDateTime.now());
    fileStore.setUploadUserId(userId);
    fileStore.setFilePath(newFilePath);
    fileStore.setFileSize((int) file.getSize());
    fileStore.setFileName(originalFilename);
    fileStore.setFileType("file");
    save(fileStore);
    return fileStore.getId();
  }

  @Override
  public List<FileStore> getFileList(String type, String keyword) {
    QueryWrapper<FileStore> wrapper = new QueryWrapper<>();
    wrapper.eq("upload_user_id", userUtil.getUserByRequest().getId()).or().eq("is_public", true);
    if (!"all".equals(type) && type != null) {
      wrapper.eq("file_type", type);
    }
    if (StringUtils.isNotEmpty(keyword)) {
      wrapper.like("file_name", keyword);
    }
    wrapper.orderByDesc("upload_time");
    return list(wrapper);
  }

  @Override
  public void delFile(List<String> ids) {
    String userId = userUtil.getUserByRequest().getId();
    List<FileStore> list = list(new QueryWrapper<FileStore>().in("id", ids));
    List<String> collect = list.stream().map(FileStore::getUploadUserId).distinct().collect(Collectors.toList());
    if(collect.size()>1 || !collect.get(0).equals(userId)){
      throw new RuntimeException("只能删除自己的文件，请重新勾选");
    }
    for (FileStore fileStore : list) {
      FileUtils.delFile(fileStore.getFilePath());
    }
    removeByIds(ids);
  }

  @Override
  public void download(String fileId, HttpServletResponse response) throws IOException {
    FileStore byId = getById(fileId);
    String filePath = byId.getFilePath();
    InputStream inputStream = Files.newInputStream(Paths.get(filePath));

    response.reset();
    response.setContentType("application/octet-stream");
    response.setContentLengthLong(new File(filePath).length());
    response.addHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(byId.getFileName(), "UTF-8"));
    ServletOutputStream outputStream = response.getOutputStream();
    byte[] b = new byte[1024];
    int len;
    while ((len = inputStream.read(b)) > 0) {
      outputStream.write(b, 0, len);
    }
    inputStream.close();
  }

  @Override
  public String uploadImageForBlog(MultipartFile file) {
    String suffix = FileUtils.suffix(file.getOriginalFilename());
    String name = TimeUtil.getDateTime("yyyyMMddHHmmss");
    String newFileName = name + suffix;
    try {
      file.transferTo(new File(blogImageDir + newFileName));
    } catch (IOException e) {
      throw new RuntimeException("保存文件失败");
    }
    return "https://www.huhailong.vip/res/img/blog/" + newFileName;
  }
}
